package com.zmjmall.demo.aspect;

import com.alibaba.fastjson.JSONObject;
import com.zmjmall.demo.constant.CookieConstant;
import com.zmjmall.demo.constant.RedisConstant;
import com.zmjmall.demo.enums.ResultEnum;
import com.zmjmall.demo.exception.MallAuthorizeException;
import com.zmjmall.demo.model.User;
import com.zmjmall.demo.util.CookieUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 * 前后端分离拦截登录
 *
 * @author zmj
 * @version 2018/7/03
 */
@Aspect
@Component
@Slf4j
@Order(1)
public class MallAspect {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 切入User 和 product(createProduct)  cart 判断是否登录
     *
     */
    @Pointcut("execution(public * com.zmjmall.demo.controller.UserController.*(..))" +
            "|| execution(public * com.zmjmall.demo.controller.ProductController.createProduct(..))" +
            "|| execution(public * com.zmjmall.demo.controller.AddressController.*(..))" +
            "|| execution(public * com.zmjmall.demo.controller.CartController.*(..))")
    public void verify() {
    }

    /**
     * 声明环绕通知
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("verify()")
    public Object doToken(ProceedingJoinPoint joinPoint) throws Throwable {
        //有token的话取出user
        User user = token();

        //获取入参名称
        String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
        //获取入参值
        Object[] args = joinPoint.getArgs();
        //获取目标类名
       // String simpleName = joinPoint.getSignature().getDeclaringType().getSimpleName();
        //修改入参userId的值
        for (int i = 0; i < parameterNames.length; i++) {
            if (parameterNames[i].equals("userId")) {
                args[i] = user.getId();
            }
            /*if(simpleName.equals(ProductController.class.getSimpleName())) {
                if(parameterNames[i].equals("productDTO")) {
                    ProductDTO productDTO = (ProductDTO) args[i];
                    System.out.println(productDTO);
                    productDTO.setUserId(user.getId());
                    args[i] = productDTO;
                }
            }else if(simpleName.equals(UserController.class.getSimpleName())) {

            }*/

        }
        Object result = "";

        return joinPoint.proceed(args);
    }


    private User token() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        //查询cookie
        Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
        if(null == cookie){
            log.warn("[登录校验] , cookie 中查不到token");
            throw new MallAuthorizeException(ResultEnum.FAILURE_NOTCOOKILE_TOKEN);
        }
        //查询redis
        String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX,cookie.getValue()));
        if(StringUtils.isEmpty(tokenValue)){
            log.warn("[登录校验] Redis中查不到token");
            throw new MallAuthorizeException(ResultEnum.FAILURE_NOTREDIS_TOKEN);
        }

        return JSONObject.parseObject(tokenValue, User.class);
    }

}
